﻿using System;
using System.Collections.Generic;
using System.Linq;
using SeguradoraIA.Framework;
using SeguradoraIA.Class;
using SeguradoraIA.Business;
using SeguradoraIA.Framework.Log;
using SeguradoraIA.Diagrama;
using System.Data;

namespace SeguradoraIA.Forms
{
    public partial class TreinarRede : PageBase
    {
        #region - Atributos -

        SeguradoraIAEntities ctx = new SeguradoraIAEntities();

        #endregion

        #region - Eventos -

        #region - Page_Load -
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!IsPostBack)
                {
                    this.ConfiguraTela();
                }
            }
            catch (Exception ex)
            {
                LogManager.LogException(ex);
                Response.Redirect("~/Forms/PaginaErro.aspx");
            }
        }
        #endregion

        #region - Enviar -
        public override void Enviar()
        {
            try
            {
                this.Treinar();
            }
            catch (Exception ex)
            {
                LogManager.LogException(ex);
                Response.Redirect("~/Forms/PaginaErro.aspx");
            }
        }
        #endregion

        #endregion

        #region - Metodos -

        #region - ConfiguraTela -
        private void ConfiguraTela()
        {
            this.ucBotoesPadrao.ExibeBotaoEnviar = true;
            this.ucBotoesPadrao.ExibirBotoes();
            this.ucBotoesPadrao.ValidationGroupBtnEnviar = "vgTaxa";
        }
        #endregion

        #region - Metodos -
        private void Treinar()
        {
            double taxaAprendizagem = txtTaxaAprendizagem.Text.ToDouble();

            if (taxaAprendizagem == 0)
            {
                ShowAlert("Taxa de Aprendizagem inválida!");
            }
            else
            {
                PerceptronCODE perceptronCODE = new PerceptronCODE();

                int idResultadoSelecione = EnumDomain.ResultadoEsperadoBDEnum.Selecione.GetHashCode();
                int idResultadoCalculado = EnumDomain.ResultadoEsperadoBDEnum.Calculado.GetHashCode();

                List<Perfil> listaPerfil = ctx.Perfil.Where(x => x.IdResultadoEsperado != idResultadoCalculado && x.IdResultadoEsperado != idResultadoSelecione).ToList();

                if (listaPerfil.Count() > 0)
                {
                    var listaCustom = (from x in listaPerfil
                                       select new EntradaDataTable
                                       {
                                           IdBairro = x.IdBairro,
                                           IdCursoFormacao = x.IdCursoFormacao,
                                           IdGrauInstrucao = x.IdGrauInstrucao,
                                           IdIdade = x.IdIdade,
                                           IdMarcaCarro = x.IdMarcaCarro,
                                           IdProfissao = x.IdProfissao,
                                           IdSinistro = x.IdSinistro,
                                           IdTempoHabilitacao = x.IdTempoHabilitacao,
                                           IdTipoCarro = x.IdTipoCarro,
                                           IdValorCarro = x.IdValorCarro,
                                           //Limiar = -1,
                                       }).ToList();

                    DataTable dtPerfil = Utilities.ListToDataTable<EntradaDataTable>(listaCustom);

                    double[] peso = perceptronCODE.RecuperarArrayPeso();

                    int[] desejado = listaPerfil.Select(x => x.IdResultadoEsperado).ToList().ToArray();

                    for (int i = 0; i < desejado.Length; i++)
                    {
                        if (desejado[i] == EnumDomain.ResultadoEsperadoBDEnum.AltoRisco.GetHashCode())
                        {
                            desejado[i] = EnumDomain.ResultadoEsperadoEnum.AltoRisco.GetHashCode();
                        }
                        else
                        {
                            desejado[i] = EnumDomain.ResultadoEsperadoEnum.BaixoRisco.GetHashCode();
                        }
                    }

                    double[] saida = new double[listaPerfil.Count];

                    perceptronCODE.neuronio(ref peso, ref desejado, ref saida, taxaAprendizagem, dtPerfil);

                    listaPerfil.ForEach(x => x.IdResultadoEsperado = EnumDomain.ResultadoEsperadoBDEnum.Calculado.GetHashCode());

                    ctx.SaveChanges();

                    Peso pesoBD = ctx.Peso.FirstOrDefault();

                    pesoBD.PesoBairro = peso[0];
                    pesoBD.PesoCursoFormacao = peso[1];
                    pesoBD.PesoGrauInstrucao = peso[2];
                    pesoBD.PesoIdade = peso[3];
                    pesoBD.PesoMarcaCarro = peso[4];
                    pesoBD.PesoProfissao = peso[5];
                    pesoBD.PesoSinistro = peso[6];
                    pesoBD.PesoTempoHabilitacao = peso[7];
                    pesoBD.PesoTipoCarro = peso[8];
                    pesoBD.PesoValorCarro = peso[9];

                    ctx.SaveChanges();

                    ShowAlert("Rede treinada com sucesso!", "Default.aspx");
                }
                else
                {
                    ShowAlert("Não existem novos perfis para treinar a rede!");
                }
            }
        }
        #endregion

        #endregion
    }
}